#include "glrenderer.h"
#include<GL/gl.h>
#include<qdebug.h>
#include<GL/glu.h>

glRenderer::glRenderer()
{
    index=nullptr;
}

//绘制函数
void glRenderer::draw(geoMap *map)
{
    for(auto &layer:map->geoLayers)
    {
        draw(layer);
    }
}

void glRenderer::draw(geoLayer *layer)
{
    for(auto &object:layer->geoObjects)
    {
        if(object->type=="Point")   draw(dynamic_cast<geoPoint *>(object));
        else if(object->type=="MultiPoint") draw(dynamic_cast<geoMultiPoint *>(object));
        else if(object->type=="LineString") draw(dynamic_cast<geoLineString *>(object));
        else if(object->type=="MultiLineString")    draw(dynamic_cast<geoMultiLineString *>(object));
        else if(object->type=="Polygon")    draw(dynamic_cast<geoPolygon *>(object));
        else if(object->type=="MultiPolygon")   draw(dynamic_cast<geoMultiPolygon *>(object));
    }
}

void glRenderer::draw(geoPoint *point)
{
    glBegin(GL_POINT);
        glVertex2d(point->projectedCoordinates[0].rx(),point->projectedCoordinates[0].ry());
    glEnd();
}

void glRenderer::draw(geoLineString *lineString)
{
    glColor3b(-1,1,0);
    glBegin(GL_LINES);
        for(auto &point:lineString->projectedCoordinates)
        {
            glVertex2d(point.rx(),point.ry());
        }
    glEnd();
}

void glRenderer::draw(geoPolygon *polygon)
{
    glColor3f(1,0,0);
    glBegin(GL_LINE_STRIP);
        for(auto &point:polygon->projectedCoordinates)
        {
            glVertex2d(point.rx(),point.ry());
        }
    glEnd();
    //绘制填充面
    GLdouble vertexs[polygon->projectedCoordinates.size()][3];
    for(int i=0;i<polygon->projectedCoordinates.size();i++)
    {
        vertexs[i][0]=polygon->projectedCoordinates[i].x();
        vertexs[i][1]=polygon->projectedCoordinates[i].y();
        vertexs[i][2]=0;
    }
    GLUtesselator *tess = gluNewTess();//创建网格器

    //设置回调函数
    gluTessCallback(tess, GLU_TESS_BEGIN,(void (__stdcall *)(void))glBegin);
    gluTessCallback(tess, GLU_VERTEX, (void (__stdcall *)(void))glVertex3dv);
    gluTessCallback(tess,GLU_TESS_END,(void (__stdcall *)(void))glEnd);

    glColor3f(0,1,0);

    gluTessBeginPolygon(tess,nullptr);//传入非凸多边形
        gluTessBeginContour(tess);//多边形回路
            for(auto &vertex:vertexs)
            {
                gluTessVertex(tess,vertex,vertex);
            }
        gluTessEndContour(tess);
    gluTessEndPolygon(tess);

    gluDeleteTess(tess);//删除网格器
}

void glRenderer::draw(geoMultiPoint *multiPoint)
{
    glColor3b(-1,1,0);
    glBegin(GL_POINTS);
        for(auto &point:multiPoint->projectedCoordinates)
        {
            glVertex2d(point.rx(),point.ry());
        }
    glEnd();
}

void glRenderer::draw(geoMultiLineString *multiLineString)
{
    for(auto &lineString:multiLineString->lineStrings)
    {
        draw(lineString);
    }
}

void glRenderer::draw(geoMultiPolygon *multiPolygon)
{
        float r,g,b;
        float lineWidth;
        if(multiPolygon->isRendered==true)
            multiPolygon->renderStyle.getFillColor(r,g,b);
        else {r=0;g=0.5f;b=0.1f;}//无SLD情况

        for(auto &polygon:multiPolygon->polygons)
        {
            //绘制填充面
            GLdouble vertexs[polygon->projectedCoordinates.size()][3];
            for(int i=0;i<polygon->projectedCoordinates.size();i++)
            {
                vertexs[i][0]=polygon->projectedCoordinates[i].x();
                vertexs[i][1]=polygon->projectedCoordinates[i].y();
                vertexs[i][2]=0;
            }
            GLUtesselator *tess = gluNewTess();//创建网格器

            //设置回调函数
            gluTessCallback(tess, GLU_TESS_BEGIN,(void (__stdcall *)(void))glBegin);
            gluTessCallback(tess, GLU_VERTEX, (void (__stdcall *)(void))glVertex3dv);
            gluTessCallback(tess,GLU_TESS_END,(void (__stdcall *)(void))glEnd);

            if(multiPolygon->isSearched==true)  glColor3f(1,0,0);
            else if(multiPolygon->isSelected==true) glColor3f(0,1,1);
            else    glColor3f(r,g,b);

            gluTessBeginPolygon(tess,nullptr);//传入非凸多边形
                gluTessBeginContour(tess);//多边形回路
                    for(auto &vertex:vertexs)
                    {
                        gluTessVertex(tess,vertex,vertex);
                    }
                gluTessEndContour(tess);
            gluTessEndPolygon(tess);

            gluDeleteTess(tess);//删除网格器

            //绘制边界
            if(multiPolygon->isSearched==true)
            {
                glColor3f(1,0,0);
                glLineWidth(1);
            }
            else if(multiPolygon->isSelected==true)
            {
                glColor3f(0,1,1);
                glLineWidth(1);
            }
            else
            {
                if(multiPolygon->isRendered==true)
                {
                    multiPolygon->renderStyle.getLineColor(r,g,b);
                    multiPolygon->renderStyle.getLineWidth(lineWidth);
                    glColor3f(r,g,b);
                    glLineWidth(lineWidth);
                }
                else
                {
                    glColor3f(0.2f,0.2f,0.2f);
                    glLineWidth(1);
                }
            }
            glBegin(GL_LINE_STRIP);
                for(auto &point:polygon->projectedCoordinates)
                {
                    glVertex2d(point.rx(),point.ry());
                }
            glEnd();
        }
}

bool glRenderer::setPaintIndex(spatialIndex *index)
{
    if(index!=nullptr)
    {
        this->index=index;
        return true;
    }
    else
    {
        qDebug()<<"当前要画的索引为空。";
        return false;
    }
}

bool glRenderer::drawIndex()
{
    if(index!=nullptr)
    {
        QVector<cellForIndex *> cells=index->getPaintCells();
        glColor3b(0,0,0);
        for(auto &cell:cells)
        {
            glBegin(GL_LINE_LOOP);
                    glVertex2d(cell->minX,cell->minY);
                    glVertex2d(cell->minX,cell->maxY);
                    glVertex2d(cell->maxX,cell->maxY);
                    glVertex2d(cell->maxX,cell->minY);
            glEnd();
        }
        return true;
    }
    else return false;
}
